<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>原型链继承解析</title>
  </head>
  <body>
    <h3>原型链继承解析</h3>
    <h4>由于要打印原型对象，在浏览器操作比较方便，就用了html文件。</h4>
    <script>
      // 父类
      function Parent(name, age) {
        // 基本数据类型
        this.name = name;
        this.age = age;

        // 父类内部方法
        this.sayName = function () {
          console.log("我的名字：", this.name);
        };
      }

      // 父类原型链方法 (这个跟原型链继承只有半毛钱关系...)
      Parent.prototype.sayAge = function () {
        console.log("我的年龄：", this.age);
      };

      // 子类，不同工种
      function Children(name, age, job) {
        // 原型链继承无法通过super 传递给父类，只能通过覆盖的形式了
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayJob = function () {
          console.log("我的工作：", this.job);
        };
      }

      // 原型链继承，构造函数的原型，是一个对象，才会在内存在分配空间，所以是需要实例化的。
      // 这边只写了一个子类，如果是多个子类，其实就会实例化多个原型对象，一般数据不会相互影响，除了复合数据类型，这边不进行验证...
      Children.prototype = new Parent();
      Children.prototype.constructor = Children;

      class Parent2 {
        constructor(name, age, dataA, dataB) {
          // 基本数据类型
          this.name = name;
          this.age = age;
          this.sayName = function () {
            console.log(this.data);
          };
        }
        sayAge() {
          console.log("我的年龄：", this.age);
        }
      }
      class Children2 extends Parent2 {
        constructor(name, age, job) {
          super(name, age);
          this.job = job;

          this.sayJob = function () {
            console.log("我的工作：", this.job);
          };
        }
      }

      let testParent = new Parent();
      let testParent2 = new Parent2();

      // 因为原型链的集成，只是数据混乱这个bug，其他都正常，所以可以直接对比
      console.log(testParent);
      console.log(testParent2);

      let testChildren = new Children();
      let testChildren2 = new Children2();

      console.log(testChildren);
      console.log(testChildren2);

      class Rectangle {
        #height = 0;
        #width;
        constructor(height, width) {
          this.#height = height;
          this.#width = width;
        }

        get height() {
          return this.#height;
        }

        set height(n) {
          this.#height = n;
        }
      }

      class Rectangle2 {
        constructor(height, width) {
          this._height = height;
          this.width = width;
        }

        get height() {
          return this.height;
        }

        set height(n) {
          this.height = n;
        }
      }

      let rect = new Rectangle(10, 20);
      rect["#height"] = 50;
      console.log(rect);
      let rect2 = new Rectangle2(10, 20);
      console.log(rect2);
    </script>
  </body>
</html>
